﻿using Abp.Authorization;
using Abp.Collections.Extensions;
using Abp.Domain.Repositories;
using Abp.Extensions;
using Abp.Linq.Extensions;
using Microsoft.EntityFrameworkCore;
using Mt.Site.Application.AccessStatistics.Dto;
using Mt.Site.Core.AccessStatistics.Entities;
using Mt.Site.Core.AccessStatistics.Features;
using Mt.Site.Core.AccessStatistics.Permissions;
using Mt.Site.Core.MultiTenancy;
using Mt.Site.Core.Navigations.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Mt.Site.Application.AccessStatistics
{
    public partial class VisitStatisticAppService: MtSiteAppServiceBase,IVisitStatisticAppService
    {
        private readonly IRepository<AccessGeneral> _AccessGeneralRepository;

        private readonly IRepository<AccessData,long> _AccessDataRespository;

        private readonly IVisitStatisticHelper _visitStatisticHelper;

        private readonly IRepository<Menu, Guid> _MenuRepository;

        private readonly TenantManager _tenantManager;
        public VisitStatisticAppService(
                IRepository<AccessGeneral> AccessGeneralRepository, 
                IRepository<AccessData, long> AccessDataRespository,
                IVisitStatisticHelper visitStatisticHelper,
                IRepository<Menu, Guid> MenuRepository,
                TenantManager tenantManager)
        {
            _AccessGeneralRepository = AccessGeneralRepository;
            _AccessDataRespository = AccessDataRespository;
            _visitStatisticHelper = visitStatisticHelper;
            _MenuRepository = MenuRepository;
            _tenantManager = tenantManager;


        }

        [AbpAuthorize(ASPermissions.Pages_Manage_AccessStatistics_Query)]
        public async Task<GeneralStatisticDto> GetGeneralStatisticData()
        {
            var entity = await _AccessGeneralRepository.FirstOrDefaultAsync(item=>item.Id != 0);
            if (entity != null)
            {
                var GeneralStatisticDto = new GeneralStatisticDto();
                var allDays = 0;
                GeneralStatisticDto.StartVisitTime = _visitStatisticHelper.DateToString(entity.StartTime);
                GeneralStatisticDto.LastTime = _visitStatisticHelper.DateToString(entity.LastVisitedDate);
                if (entity.StartTime != null && entity.LastVisitedDate != null)
                {
                    allDays = ((DateTime)entity.LastVisitedDate - (DateTime)entity.StartTime).Days;
                    GeneralStatisticDto.StatisticsDays = allDays.ToString();
                }
                else
                {
                    GeneralStatisticDto.StatisticsDays = "0";
                }
                GeneralStatisticDto.AllVisitNumber = entity.Pv_TotolNum.ToString();
                GeneralStatisticDto.MaxVisitNumber = entity.Pv_Max_InADay.ToString();
                GeneralStatisticDto.MaxVisitTime = _visitStatisticHelper.DateToString(entity.Pv_Max_InADay_Date);

                var todayData = new GeneralData();
                todayData.PvNumber = entity.Pv_Today.ToString();
                todayData.UvNumber = entity.Uv_Today.ToString();
                todayData.IPNumber = entity.Ip_Today.ToString();
                todayData.NewVisitNumber = entity.New_Today.ToString();
                todayData.AvgVisitNumber = _visitStatisticHelper.AvgVisitNumCalc(entity.Uv_Today, entity.Pv_Today).ToString();
                todayData.OutVisitNumber = _visitStatisticHelper.BounceRateCalc(entity.Tiaochu_Today, entity.Pv_Today).ToString();
                todayData.AvgVisitTime = _visitStatisticHelper.NumberToTime(entity.LengthOfStay_Today, entity.Pv_Today,entity.Tiaochu_Today);
                
                GeneralStatisticDto.TodayData = todayData;

                var yesterdayData = new GeneralData();
                yesterdayData.PvNumber = entity.Pv_Yestoday.ToString();
                yesterdayData.UvNumber = entity.Uv_Yestoday.ToString();
                yesterdayData.IPNumber = entity.Ip_Yestoday.ToString();
                yesterdayData.NewVisitNumber = entity.New_Yestoday.ToString();

                yesterdayData.AvgVisitNumber = _visitStatisticHelper.AvgVisitNumCalc(entity.Uv_Yestoday, entity.Pv_Yestoday).ToString();
                yesterdayData.OutVisitNumber = _visitStatisticHelper.BounceRateCalc(entity.Tiaochu_Yestoday, entity.Pv_Yestoday).ToString();
                yesterdayData.AvgVisitTime = _visitStatisticHelper.NumberToTime(entity.LengthOfStay_Yestoday, entity.Pv_Yestoday, entity.Tiaochu_Yestoday).ToString();

                GeneralStatisticDto.YesterdayData = yesterdayData; 

                if (allDays != 0)
                {
                    var AvgDayData = new GeneralData();
                    var avg_pv = entity.Pv_TotolNum / allDays * 1.0;
                    var avg_uv = entity.Uv_TotolNum / allDays * 1.0;
                    var avg_ip = entity.Ip_TotolNum / allDays * 1.0;
                    var avg_new = entity.New_TotolNum / allDays * 1.0;
                    AvgDayData.PvNumber = Math.Round(avg_pv, 2).ToString();
                    AvgDayData.UvNumber = Math.Round(avg_uv, 2).ToString();
                    AvgDayData.IPNumber = Math.Round(avg_ip, 2).ToString();
                    AvgDayData.NewVisitNumber = Math.Round(avg_new, 2).ToString();

                    AvgDayData.AvgVisitNumber = _visitStatisticHelper.AvgVisitNumCalc(entity.Uv_TotolNum, entity.Pv_TotolNum).ToString();
                    AvgDayData.OutVisitNumber = _visitStatisticHelper.BounceRateCalc(entity.Tiaochu_TotolNum, entity.Pv_TotolNum).ToString();
                    AvgDayData.AvgVisitTime = _visitStatisticHelper.NumberToTime(entity.LengthOfStay_Totol, entity.Pv_TotolNum, entity.Tiaochu_TotolNum);
                    GeneralStatisticDto.AvgDayData = AvgDayData;
                }


                var monthData = new GeneralData();
                monthData.PvNumber = entity.Pv_Month.ToString();
                monthData.UvNumber = entity.Uv_Month.ToString();
                monthData.IPNumber = entity.Ip_Month.ToString();
                monthData.NewVisitNumber = entity.New_Month.ToString();

                monthData.AvgVisitNumber = _visitStatisticHelper.AvgVisitNumCalc(entity.Uv_Month, entity.Pv_Month).ToString();
                monthData.OutVisitNumber = _visitStatisticHelper.BounceRateCalc(entity.Tiaochu_Month, entity.Pv_Month).ToString();
                monthData.AvgVisitTime = _visitStatisticHelper.NumberToTime(entity.LengthOfStay_Month, entity.Pv_Month, entity.Tiaochu_Month);
  
                GeneralStatisticDto.MonthData = monthData;

                var yearData = new GeneralData();
                yearData.PvNumber = entity.Pv_Year.ToString();
                yearData.UvNumber = entity.Uv_Year.ToString();
                yearData.IPNumber = entity.Ip_Year.ToString();
                yearData.NewVisitNumber = entity.New_Year.ToString();

                yearData.AvgVisitNumber = _visitStatisticHelper.AvgVisitNumCalc(entity.Uv_Year, entity.Pv_Year).ToString();
                yearData.OutVisitNumber = _visitStatisticHelper.BounceRateCalc(entity.Tiaochu_Year, entity.Pv_Year).ToString();
                yearData.AvgVisitTime = _visitStatisticHelper.NumberToTime(entity.LengthOfStay_Year, entity.Pv_Year, entity.Tiaochu_Year);
              
                GeneralStatisticDto.YearData = yearData;

                var lineTime = DateTime.Now.AddMinutes(-30);

                var query = from data in _AccessDataRespository.GetAll().Where(item => item.VisitTime >= lineTime)
                            group data by data.SessionId into t
                            select t.Key;

                var lineNum = query.Count();
                GeneralStatisticDto.InlineNumber = lineNum.ToString();
               
                return GeneralStatisticDto;
            }
            return null;
        }

        #region 趋势分析
        // 实时访客
        [AbpAuthorize(ASPermissions.Pages_Manage_AccessStatistics_Query)]
        public async Task<RealTimeDto> GetRealTimeData()
        {
            var nowTime = DateTime.Now;
            var date = nowTime.AddMinutes(-29);
            var list = await _AccessDataRespository.GetAllListAsync(item => item.VisitTime >= date);

            var pvNumbers = new List<int>();
            var ipNumbers = new List<int>();
            var visitNumbers = new List<int>();
            var times = new List<string>();
            for (var i = date; i <= nowTime; i = i.AddMinutes(1))
            {
                var pvNumber = new List<long>();
                var visitNumber = new SortedSet<string>(); 
                var ipNumber = new SortedSet<string>(); 
                foreach (var item in list)
                {
                    if (i.Minute == item.VisitTime.Minute)
                    {
                        pvNumber.Add(item.Id);
                        visitNumber.Add(item.Acount);
                        ipNumber.Add(item.ClientIp);
                    }
                }
                pvNumbers.Add(pvNumber.Count);
                visitNumbers.Add(visitNumber.Count);
                ipNumbers.Add(ipNumber.Count);
                times.Add(i.ToString("HH:mm"));
            }
            return new RealTimeDto
            {
                Times = times,
                PvNumebrs = pvNumbers,
                VisitNumbers = visitNumbers,
                IpNumbers = ipNumbers
            };
                        
        }

        // 实时访客统计列表
        [AbpAuthorize(ASPermissions.Pages_Manage_AccessStatistics_Query)]
        public async Task<List<TodayDetailItems>> GetRealTimeTodayDatas(PagedTodayDetailInput input)
        {
            var date = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd"));
            var query = from data in _AccessDataRespository.GetAll()
                        .Where(item => item.IsEndPage == 1 && item.VisitTime >= date)
                        .WhereIf(input.Source != null, item => item.SourceType == input.Source)
                        .WhereIf(input.Device != null, item => item.FormFactor == input.Device)
                        .WhereIf(!input.Search.IsNullOrWhiteSpace(), item => item.EngineType == input.Search)
                        .WhereIf(!input.Filter.IsNullOrWhiteSpace(),
                        item => item.Title.Contains(input.Filter) || item.Browser.Contains(input.Filter) || item.Acount == input.Filter)
                        select new 
                        {
                            Area = data.City,
                            FirstPage = data.FirstPageUrl,
                            LastPage = data.Url,
                            SessionId = data.SessionId,
                            Source = data.SourceType,
                            StayLength = data.LengthOfStay,
                            VisitPages = data.PageNum,
                            VisitTime = data.VisitTime
                        };

            query = query.OrderByDescending(item => item.VisitTime);
            var list = await query.ToListAsync();
            var result = new List<TodayDetailItems>();
            foreach (var item in list)
            {
                var detailItems = new TodayDetailItems();
                detailItems.Area = item.Area;
                detailItems.FirstPage = item.FirstPage;
                detailItems.LastPage = item.LastPage;
                detailItems.SessionId = item.SessionId;
                detailItems.StayLength = item.StayLength / 1000;
                detailItems.VisitPages = item.VisitPages;
                detailItems.SessionId = item.SessionId;
                detailItems.VisitTime = item.VisitTime.ToString("HH:mm:ss");
                detailItems.Source = _visitStatisticHelper.GetVisitSourceName(item.Source);
                result.Add(detailItems);
            }
            return result;
        }


        /// <summary>
        /// 获取实时访客详细
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [AbpAuthorize(ASPermissions.Pages_Manage_AccessStatistics_Query)]
        public async Task<RealTimeDetailOut> GetRealTimeDataBySessionId(RealTimeDetailInput input)
        {
            var lastEntity = await _AccessDataRespository.FirstOrDefaultAsync(item => item.IsEndPage == 1 && item.SessionId == input.SessionId);

            if (lastEntity != null)
            {
                var result = ObjectMapper.Map<RealTimeDetailOut>(lastEntity);
                result.LastVisitTime = lastEntity.LastVisitTime.ToString("yyyy-MM-dd HH:mm:ss");
                result.IsNewVisitor = lastEntity.IsNewVisitor == 0 ? L("No") : L("Yes");
                result.CookieEnabled = lastEntity.CookieEnabled ? L("CookieEnable") : L("CookieDisEnable");
                result.SourceType = _visitStatisticHelper.GetVisitSourceName(lastEntity.SourceType);

                var list = _AccessDataRespository.Query(
                    q => q.Where(p => p.SessionId == lastEntity.SessionId)
                    .OrderByDescending(p=>p.VisitTime).ToList());

                var pathDetails = new List<VisitPathDetailDto>();

                list.ForEach(item =>
                {
                    var pathDetail = new VisitPathDetailDto();
                    pathDetail.Source = item.SourceType;
                    pathDetail.StayLength = item.LengthOfStay;
                    pathDetail.VisitTime = item.VisitTime.ToString("HH:mm:ss");
                    pathDetail.RefererUrl = item.RefererUrl;
                    pathDetail.VisitUrl = item.Url;
                    pathDetails.Add(pathDetail);
                });
                result.VisitPathDetails = pathDetails;
                return result;
            }
            return null;
        }

        [AbpAuthorize(ASPermissions.Pages_Manage_AccessStatistics_Query)]
        public async Task<TrendStatisticDto> GetTrendStatisticAnalysis(PagedTrendStatisticDataInput input)
        {
            var startTime = input.StartTime;
            var endTime = input.EndTime;
            var TenancyName = GetCurrentTenant().TenancyName;
            if (!_visitStatisticHelper.CheckTimeFormat(ref startTime,ref endTime))
            {
                return null;
            }
            var trendStatisticDto = new TrendStatisticDto();
            input.StartTime = startTime;
            input.EndTime = endTime;
            trendStatisticDto.StartTime = startTime.ToString("yyyy-MM-dd");
            trendStatisticDto.EndTime = endTime.ToString("yyyy-MM-dd");
            trendStatisticDto.IpNumber = 0;
            trendStatisticDto.NewVisits = 0;
            trendStatisticDto.PvNumber = 0;
            trendStatisticDto.UvNumber = 0;
            var sortTimeTypes = _visitStatisticHelper.CheckTimeSpan(startTime, endTime);
            trendStatisticDto.SortTimeTypes = sortTimeTypes;
            SortTimeType currentSortType = input.SortByTime;
            if (!sortTimeTypes.Contains(input.SortByTime))
            {
                currentSortType = SortTimeType.Day;
            }

            IQueryable<ClientIpQueryDto> ipQuery = null;
            IQueryable<AccoutDetailQueryDto> query = null;

            if (currentSortType == SortTimeType.Hour)  //只统计今天和昨天
            {
                if (startTime != endTime)
                {
                    return null;
                }
                var hourQuery = from data in _AccessDataRespository.GetAll()
                                .TreandStatistics(input, TenancyName)
                                .OrderByDescending(item=>item.VisitTime)
                                select new
                                {
                                    Ip = data.ClientIp,
                                    Account = data.Acount,
                                    IsBounced = data.IsBounced,
                                    IsNewVisitor = data.IsNewVisitor,
                                    LenthOfStay = data.LengthOfStay,
                                    Hour = data.Hour
                                };

                var list = await hourQuery.ToListAsync();

                var yaxis = new List<TrendYxisData>();
                var lenthOfStays = 0;
                var outNumbers = 0;
                var allHour = 23;
                if (startTime.ToString("yyyy-MM-dd") == endTime.ToString("yyyy-MM-dd") 
                    && endTime.ToString("yyyy-MM-dd") == DateTime.Now.ToString("yyyy-MM-dd"))
                {
                    allHour = DateTime.Now.Hour;
                }
                for (int i = allHour; i >= 0; i--)
                {
                    var trendYxisData = new TrendYxisData();
                    var Ips = new SortedSet<string>();
                    var Accounts = new SortedSet<string>();
                    trendYxisData.Time = i.ToString();
                    trendYxisData.pvNum = 0;
                    trendYxisData.NewVisitNum = 0;
                    var lenthOfStay = 0;
                    var outNum = 0;
                    foreach (var item in list)
                    {
                        if (item.Hour == i)
                        {
                            Ips.Add(item.Ip);
                            Accounts.Add(item.Account);
                            trendYxisData.pvNum += 1;
                            trendYxisData.NewVisitNum += item.IsNewVisitor;
                            lenthOfStay += item.LenthOfStay;
                            outNum += item.IsBounced;
                        }
                    }
                    trendYxisData.IpNum = Ips.Count();
                    trendYxisData.UvNum = Accounts.Count();
                    trendYxisData.AvgVisitTime = _visitStatisticHelper.NumberToTime(lenthOfStay, trendYxisData.pvNum, outNum);
                    trendYxisData.OutRate = _visitStatisticHelper.BounceRateCalc(outNum, trendYxisData.pvNum);
                    lenthOfStays += lenthOfStay;
                    outNumbers += outNum;
                    trendStatisticDto.IpNumber += trendYxisData.IpNum;
                    trendStatisticDto.NewVisits += trendYxisData.NewVisitNum;
                    trendStatisticDto.PvNumber += trendYxisData.pvNum;

                    yaxis.Add(trendYxisData);
                }
                trendStatisticDto.OutRate = _visitStatisticHelper.BounceRateCalc(outNumbers, trendStatisticDto.PvNumber);
                trendStatisticDto.AvgVisitTime = _visitStatisticHelper.NumberToTime(lenthOfStays, trendStatisticDto.PvNumber, outNumbers);
                trendStatisticDto.Y_axis = yaxis;

            }
            else if (currentSortType == SortTimeType.Day)
            {
                 ipQuery = from dataTwo in
                                   from data in _AccessDataRespository.GetAll()
                                  .TreandStatistics(input, TenancyName)
                                   group data by new { Ip = data.ClientIp, Time = data.DayFormart } into t
                                   select new 
                                   {
                                       Ip = t.Key.Ip,
                                       Time = t.Key.Time
                                   }
                               group dataTwo by new { Time = dataTwo.Time } into tTwo
                               select new ClientIpQueryDto
                               {
                                   IpNum = tTwo.Count(item => item.Ip != null && item.Ip != ""),
                                   Label = tTwo.Key.Time
                               };

                 query = from dataTwo in
                                from data in _AccessDataRespository.GetAll()
                                .TreandStatistics(input, TenancyName)
                                group data by new { Time = data.DayFormart, Accout = data.Acount } into t
                                select new
                                {
                                    Account = t.Key.Accout,
                                    Time = t.Key.Time,
                                    PvNum = t.Count(),
                                    OutNum = t.Sum(item => item.IsBounced),
                                    NewNum = t.Sum(item => item.IsNewVisitor),
                                    LengthOfStay = t.Sum(item => item.LengthOfStay)
                                }
                            group dataTwo by new { Time = dataTwo.Time } into tTwo
                            select new  AccoutDetailQueryDto
                            {
                                UvNum = tTwo.Count(item => item.Account != null && item.Account != ""),
                                PvNum = tTwo.Sum(item => item.PvNum),
                                NewNum = tTwo.Sum(item => item.NewNum),
                                OutNum = tTwo.Sum(item => item.OutNum),
                                LengthOfStay = tTwo.Sum(item => item.LengthOfStay),
                                Label = tTwo.Key.Time
                            };
            }
            else if (currentSortType == SortTimeType.Week)
            {
                 ipQuery =
                               from dataTwo in
                                   from data in _AccessDataRespository.GetAll()
                                  .TreandStatistics(input, TenancyName)
                                   group data by new { Ip = data.ClientIp, Time = data.SundayFormart } into t
                                   select new
                                   {
                                       Ip = t.Key.Ip,
                                       Time = t.Key.Time
                                   }
                               group dataTwo by new { Time = dataTwo.Time } into tTwo
                               select new ClientIpQueryDto
                               {
                                   IpNum = tTwo.Count(item => item.Ip != null && item.Ip != ""),
                                   Label = tTwo.Key.Time
                               };

                 query = from dataTwo in
                                from data in _AccessDataRespository.GetAll()
                                .TreandStatistics(input, TenancyName)
                                group data by new { Time = data.SundayFormart, Accout = data.Acount } into t
                                select new 
                                {
                                    Account = t.Key.Accout,
                                    Time = t.Key.Time,
                                    PvNum = t.Count(),
                                    OutNum = t.Sum(item => item.IsBounced),
                                    NewNum = t.Sum(item => item.IsNewVisitor),
                                    LengthOfStay = t.Sum(item => item.LengthOfStay)
                                }
                            group dataTwo by new { Time = dataTwo.Time } into tTwo
                            select new AccoutDetailQueryDto
                            {
                                UvNum = tTwo.Count(item => item.Account != null && item.Account != ""),
                                PvNum = tTwo.Sum(item => item.PvNum),
                                NewNum = tTwo.Sum(item => item.NewNum),
                                OutNum = tTwo.Sum(item => item.OutNum),
                                LengthOfStay = tTwo.Sum(item => item.LengthOfStay),
                                Label = tTwo.Key.Time
                            };
            }
            else if (currentSortType == SortTimeType.Month)
            {
                 ipQuery =
                               from dataTwo in
                                   from data in _AccessDataRespository.GetAll()
                                  .TreandStatistics(input, TenancyName)
                                   group data by new { Ip = data.ClientIp, Time = data.MonthFormart } into t
                                   select new
                                   {
                                       Ip = t.Key.Ip,
                                       Time = t.Key.Time
                                   }
                               group dataTwo by new { Time = dataTwo.Time } into tTwo
                               select new ClientIpQueryDto
                               {
                                   IpNum = tTwo.Count(item => item.Ip != null && item.Ip != ""),
                                   Label = tTwo.Key.Time
                               };

                 query = from dataTwo in
                                from data in _AccessDataRespository.GetAll()
                                .TreandStatistics(input, TenancyName)
                                group data by new { Time = data.MonthFormart, Accout = data.Acount } into t
                                select new
                                {
                                    Account = t.Key.Accout,
                                    Time = t.Key.Time,
                                    PvNum = t.Count(),
                                    OutNum = t.Sum(item => item.IsBounced),
                                    NewNum = t.Sum(item => item.IsNewVisitor),
                                    LengthOfStay = t.Sum(item => item.LengthOfStay)
                                }
                            group dataTwo by new { Time = dataTwo.Time } into tTwo
                            select new AccoutDetailQueryDto
                            {
                                UvNum = tTwo.Count(item => item.Account != null && item.Account != ""),
                                PvNum = tTwo.Sum(item => item.PvNum),
                                NewNum = tTwo.Sum(item => item.NewNum),
                                OutNum = tTwo.Sum(item => item.OutNum),
                                LengthOfStay = tTwo.Sum(item => item.LengthOfStay),
                                Label = tTwo.Key.Time
                            };
            }

            if (currentSortType != SortTimeType.Hour)
            {
                var ipList = await ipQuery.ToListAsync();
                var list = await query.ToListAsync();

                ipList = ipList.Reverse<ClientIpQueryDto>().ToList();
                list = list.Reverse<AccoutDetailQueryDto>().ToList();
                var trendYxisDatas = new List<TrendYxisData>();
                var lenthOfStay = 0;
                var outNum = 0;
                foreach (var item in list)
                {
                    var trendYxisData = new TrendYxisData();
                    trendYxisData.Time = item.Label;
                    trendYxisData.NewVisitNum = item.NewNum;
                    trendYxisData.pvNum = item.PvNum;
                    trendYxisData.UvNum = item.UvNum;
                    trendYxisData.AvgVisitTime = _visitStatisticHelper.NumberToTime(item.LengthOfStay, item.PvNum, item.OutNum);
                    trendYxisData.OutRate = _visitStatisticHelper.BounceRateCalc(item.OutNum, item.PvNum);


                    foreach (var ipItem in ipList)
                    {
                        if (ipItem.Label == item.Label)
                        {
                            trendYxisData.IpNum = ipItem.IpNum;
                            trendStatisticDto.IpNumber += ipItem.IpNum;
                        }
                    }
                    lenthOfStay += item.LengthOfStay;
                    outNum += item.OutNum;
                    trendStatisticDto.PvNumber += item.PvNum;
                    trendStatisticDto.UvNumber += item.UvNum;
                    trendStatisticDto.NewVisits += item.NewNum;
                    trendYxisDatas.Add(trendYxisData);
                }
                trendStatisticDto.OutRate = _visitStatisticHelper.BounceRateCalc(outNum, trendStatisticDto.PvNumber);
                trendStatisticDto.AvgVisitTime = _visitStatisticHelper.NumberToTime(lenthOfStay, trendStatisticDto.PvNumber, outNum);
                trendStatisticDto.Y_axis = trendYxisDatas;
            }

            return trendStatisticDto;
        }
        #endregion


        #region 详细记录
        [AbpAuthorize(ASPermissions.Pages_Manage_AccessStatistics_Query)]
        public async Task<AccessDetailData> GetAccessDetailRecordAsync(AccessDetailRecordInput input)
        {
            var  startTime = input.StartTime;
            var  endTime = input.EndTime;

            if (!_visitStatisticHelper.CheckTimeFormat(ref startTime, ref endTime))
            {
                return null;
            }
            var accessDetailData = new AccessDetailData();
            input.StartTime = startTime;
            input.EndTime = endTime;
            var uvQuery = from data in _AccessDataRespository.GetAll()
                          .AccessDetailRecordQuery(input)
                          group data by new { uv = data.Acount } into t
                          select new {
                              UvNum = t.Key.uv,
                              OutNum = t.Sum(item => item.IsBounced),
                              StayLength = t.Sum(item => item.LengthOfStay),
                              NewNum = t.Sum(item => item.IsNewVisitor),
                              PvNum = t.Count()
                          };
            accessDetailData.StartTime = startTime.ToString("yyyy-MM-dd");
            accessDetailData.EndTime = endTime.ToString("yyyy-MM-dd");
            accessDetailData.UvNum = uvQuery.Count(item => item.UvNum != null && item.UvNum != "");
            var outNum  = uvQuery.Sum(item => (int?)item.OutNum) ?? 0;
            
            accessDetailData.NewNum = uvQuery.Sum(item => (int?)item.NewNum) ?? 0;
            accessDetailData.PvNum = uvQuery.Sum(item => (int?)item.PvNum) ?? 0;
            var stayLength = uvQuery.Sum(item => (int?)item.StayLength) ?? 0;

            accessDetailData.OutNum = _visitStatisticHelper.BounceRateCalc(outNum, accessDetailData.PvNum);
            accessDetailData.AvgVisitTime = _visitStatisticHelper.NumberToTime(stayLength, accessDetailData.PvNum, outNum);

            var IpQuery = from data in _AccessDataRespository.GetAll()
                          .AccessDetailRecordQuery(input)
                          group data by new { Ip = data.ClientIp} into t
                          select new
                          {
                              IpNum = t.Key.Ip
                          };
            accessDetailData.IpNum = IpQuery.Count(item => item.IpNum != null && item.IpNum != "");


            var query = from data in _AccessDataRespository.GetAll()
                        .AccessDetailRecordQuery(input)
                        .Where(item => item.IsEndPage == 1)
                        select new
                        {
                            Area = data.City,
                            VisitTime = data.VisitTime,
                            Source = data.SourceType,
                            FirstPage = data.FirstPageUrl,
                            LastPage = data.Url,
                            StayLength = data.LengthOfStay,
                            VisitPages = data.FrequentVisits,
                            SessionId = data.SessionId
                        };
            var list = await query.ToListAsync();

            var records = new List<AccessDetailItemDto>();
            foreach (var item in list)
            {
                var record = new AccessDetailItemDto();
                record.Area = item.Area;
                record.FirstPage = item.FirstPage;
                record.LastPage = item.LastPage;
                record.SessionId = item.SessionId;
                record.Source = _visitStatisticHelper.GetVisitSourceName(item.Source);
                record.StayLength = item.StayLength / 1000;
                record.VisitPages = item.VisitPages;
                record.VisitTime = item.VisitTime.ToString("yyyy-MM-dd HH:mm:ss");
                records.Add(record);
            }
            accessDetailData.AccessDetailDatas = records;
            return accessDetailData;

        }

        [AbpAuthorize(ASPermissions.Pages_Manage_AccessStatistics_Query)]
        public async Task<AccessDetailRecordDto> GetAccessDetailRecordItemsAsync(AccessDetailItemInput input)
        {
            var entity = await _AccessDataRespository.FirstOrDefaultAsync(item => item.IsEndPage == 1 && item.SessionId == input.SessionId);

            if (entity != null)
            {
                var recordDto = ObjectMapper.Map<AccessDetailRecordDto>(entity);
                recordDto.LastVisitTime = entity.LastVisitTime.ToString("yyyy-MM-dd HH:mm:ss");
                recordDto.IsNewVisitor = entity.IsNewVisitor == 0 ? L("No") : L("Yes");
                recordDto.CookieEnabled = entity.CookieEnabled ? L("CookieEnable") : L("CookieDisEnable");
                recordDto.SourceType = _visitStatisticHelper.GetVisitSourceName(entity.SourceType);
                var list = _AccessDataRespository.Query(
                    q => q.Where(p => p.SessionId == entity.SessionId)
                    .OrderByDescending(p => p.VisitTime).ToList());

                var pathDetails = new List<AccessDetailItem>();

                list.ForEach(item =>
                {
                    var pathDetail = new AccessDetailItem();
                    pathDetail.StayLength = item.LengthOfStay / 1000;
                    pathDetail.VisitTime = item.VisitTime.ToString("HH:mm:ss");
                    pathDetail.RefererUrl = item.RefererUrl;
                    pathDetail.VisitUrl = item.Url;
                    pathDetails.Add(pathDetail);
                });
                recordDto.VisitPathDetails = pathDetails;
                return recordDto;
            }
            return null;
        }
        #endregion

        [AbpAuthorize(ASPermissions.Pages_Manage_AccessStatistics_Query)]
        public async Task<bool> SetCloseOrOpen(bool value)
        {
           await  _tenantManager.SetFeatureValueAsync(GetCurrentTenant().Id, ASFeatures.ASFeature, value.ToString());
            return value;
        }
    }
}
